package imp

import (
	sqlc "bgs/db/sqlc"
	brandFollowGrpc "bgs/grpc/gen/service/brand_follow"
	"bgs/grpc/gen/shared/message"
	"context"
)

/****************************************************************************************/
/*                               brand_follow entity of helper                           */
/****************************************************************************************/

func transformBrandFollowEntityToPb(BrandFollow sqlc.BrandFollow) *brandFollowGrpc.BrandFollowEntity {
	return &brandFollowGrpc.BrandFollowEntity{
		Id:              BrandFollow.ID,
		UserId:          BrandFollow.UserID,
		FollowedBrandId: BrandFollow.FollowedBrandID,
		Followed:        sqlc.GoTimeToPBTimestamp(BrandFollow.Followed),
		Remark:          BrandFollow.Remark.String,
	}
}

/****************************************************************************************/
/*                               brand_follow entity of cmd                              */
/****************************************************************************************/

// UpsertBrandFollow 创建用户关注关系
func (s *BrandAPIService) UpsertBrandFollow(ctx context.Context, req *brandFollowGrpc.UpsertBrandFollowRequest) (res *brandFollowGrpc.UpsertBrandFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_followImp->UpsertBrandFollow:%v", req)
	res = &brandFollowGrpc.UpsertBrandFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpsertBrandFollowParams{
		UserID:          req.UserId,
		FollowedBrandID: req.FollowedBrandId,
		Followed:        sqlc.PBTimestampToGoTime(req.Followed),
	}
	brandFollow, err := s.dao.Q.UpsertBrandFollow(ctx, arg)

	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandFollow = transformBrandFollowEntityToPb(brandFollow)
	return
}

// UpdateBrandFollow 更新用户关注关系
func (s *BrandAPIService) UpdateBrandFollow(ctx context.Context, req *brandFollowGrpc.UpdateBrandFollowRequest) (res *brandFollowGrpc.UpdateBrandFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_followImp->UpdateBrandFollow:%v", req)
	res = &brandFollowGrpc.UpdateBrandFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpdateBrandFollowParams{
		ID:     req.Id,
		Remark: sqlc.NSFromString(req.Remark),
	}
	brandFollow, err := s.dao.Q.UpdateBrandFollow(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandFollow = transformBrandFollowEntityToPb(brandFollow)
	return
}

/****************************************************************************************/
/*                               brand_follow entity of query                            */
/****************************************************************************************/

// GetBrandFollow 获取单个用户关注
func (s *BrandAPIService) GetBrandFollow(ctx context.Context, req *brandFollowGrpc.GetBrandFollowRequest) (res *brandFollowGrpc.GetBrandFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_followImp->GetBrandFollow:%v", req)
	res = &brandFollowGrpc.GetBrandFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	brandFollow, err := s.dao.Q.GetBrandFollow(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.BrandFollow = transformBrandFollowEntityToPb(brandFollow)
	return
}

/****************************************************************************************/
/*                            brand_followJoins entity of helper                            */
/****************************************************************************************/

func transformBrandFollowWithBrandAndBrandStatEntityToPb(row sqlc.ListBrandFollowWithBrandAndBrandStatsRow) *brandFollowGrpc.BrandFollowWithBrandAndBrandStatEntity {
	return &brandFollowGrpc.BrandFollowWithBrandAndBrandStatEntity{
		// brand_follow
		Id:              row.ID,
		UserId:          row.UserID,
		FollowedBrandId: row.FollowedBrandID,
		Followed:        sqlc.GoTimeToPBTimestamp(row.Followed),
		Remark:          row.Remark.String,

		// brand
		FollowedBrandName: row.Name,
		FollowedBrandPic:  row.Pic,

		// brand_stat
		FansCount:                  row.FansCount,
		AdminCount:                 row.AdminCount,
		PublishActivityCount:       row.PublishActivityCount,
		SpokesmanCount:             row.SpokesmanCount,
		EndorseRequestToAuditCount: row.EndorseRequestToAuditCount,
	}
}

func mapBrandFollowWithBrandAndBrandStatEntityToPb(list []sqlc.ListBrandFollowWithBrandAndBrandStatsRow, f func(sqlc.ListBrandFollowWithBrandAndBrandStatsRow) *brandFollowGrpc.BrandFollowWithBrandAndBrandStatEntity) []*brandFollowGrpc.BrandFollowWithBrandAndBrandStatEntity {
	r := make([]*brandFollowGrpc.BrandFollowWithBrandAndBrandStatEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                            brand_followJoins entity of query                             */
/****************************************************************************************/

// ListBrandFollowWithBrandAndBrandStats  获取关注的用户及其统计信息
func (s *BrandAPIService) ListBrandFollowWithBrandAndBrandStats(ctx context.Context, req *brandFollowGrpc.ListBrandFollowWithBrandAndBrandStatsRequest) (res *brandFollowGrpc.ListBrandFollowWithBrandAndBrandStatsResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("brand_followImp->ListBrandFollowWithBrandAndBrandStats:%v", req)

	res = &brandFollowGrpc.ListBrandFollowWithBrandAndBrandStatsResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	total, err := s.dao.Q.CountBrandFollowWithBrandAndBrandStats(ctx, req.UserId)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}
	arg := sqlc.ListBrandFollowWithBrandAndBrandStatsParams{
		Limit:  req.Limit,
		Offset: req.Offset,
		UserID: req.UserId,
	}
	brandFollowWithBrandAndBrandStats, err := s.dao.Q.ListBrandFollowWithBrandAndBrandStats(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.BrandFollowWithBrandAndBrandStats = mapBrandFollowWithBrandAndBrandStatEntityToPb(brandFollowWithBrandAndBrandStats, transformBrandFollowWithBrandAndBrandStatEntityToPb)
	return
}
